﻿namespace Socket.Core
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Text;

    public class GateMessage : IMessage
    {
        private int MessageHeadCount;

        public GateMessage()
        {
            this.MessageHeadCount = 4;
            this.MethodCode = 0;
        }

        public GateMessage(int methodCode, byte[] message)
        {
            this.MethodCode = methodCode;
            this.Body = message;
            this.MessageHeadCount = 4;
        }

        public GateMessage(int methodCode, string message, Encoding encoding)
            : this(methodCode, encoding.GetBytes(message))
        {
        }

        public virtual byte[] GetReceiveBytes()
        {
            if (this.Body.Length >= this.MessageHeadCount)
            {
                int count = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToUInt16(this.Body, 0));
                this.MethodCode = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToUInt16(this.Body, 2));

                byte[] dst = new byte[count];
                Buffer.BlockCopy(this.Body, this.MessageHeadCount, dst, 0, count);
                return dst;
            }
            return null;
        }

        public virtual byte[] GetSendBytes()
        {
            byte[] buffer;
            short msgId = System.Net.IPAddress.HostToNetworkOrder((short)this.MethodCode);
            short len = System.Net.IPAddress.HostToNetworkOrder((short)(this.Body.Length + this.MessageHeadCount));
            
            if (this.Body != null)
            {
                buffer = new byte[this.Body.Length + this.MessageHeadCount];
                buffer.GetBytes(len, 0);
            }
            else
            {
                buffer = new byte[this.MessageHeadCount];
                buffer.GetBytes(len, 0);
            }

            buffer.GetBytes(msgId, 2);
            
            if (this.Body != null)
            {
                Buffer.BlockCopy(this.Body, 0, buffer, this.MessageHeadCount, this.Body.Length);
            }

            return buffer;
        }

        public byte[] Body { get; protected set; }

        protected int MethodCode { get; set; }
    }
}

